package my.lang.parser;

import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;

import static com.intellij.psi.TokenType.BAD_CHARACTER;
import static com.intellij.psi.TokenType.WHITE_SPACE;
import static lang.psi.MyLanguageTypes.*;

%%

%{
  public _MyLanguageLexer() {
    this((java.io.Reader)null);
  }
%}

%public
%class _MyLanguageLexer
%implements FlexLexer
%function advance
%type IElementType
%unicode

EOL=\R
WHITE_SPACE=\s+

IDENTIFIER=[a-zA-Z][a-zA-Z_0-9]*
LINE_COMMENT=("//".*)
USI_VALUE=(\"[a-zA-Z_0-9]+(:[a-zA-Z_0-9]+)*:"//"([-/?&=.:;]|[a-zA-Z_0-9])*\")
USI_KEY_NAME=(\"usi\")
JSON_KEY_NAME=(\"([-/]|[a-zA-Z_0-9])+\")
STRING=('([^'\\]|\\.)*'|\"([^\"\\]|\\\"|\\'|\\)*\")
NUMBER=[+-]?([0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)?)

%%
<YYINITIAL> {
  {WHITE_SPACE}        { return WHITE_SPACE; }

  "{"                  { return MY_BRACE_LEFT; }
  "}"                  { return MY_BRACE_RIGHT; }
  "["                  { return MY_BRACKET_LEFT; }
  "]"                  { return MY_BRACKET_RIGHT; }
  "("                  { return MY_PAREN_LEFT; }
  ")"                  { return MY_PAREN_RIGHT; }
  ":"                  { return MY_COLON; }
  ";"                  { return MY_SEMICOLON; }
  ","                  { return MY_COMMA; }
  "="                  { return MY_ASSIGN; }
  "."                  { return MY_DOT; }
  "null"               { return MY_NULL; }
  "true"               { return MY_TRUE; }
  "false"              { return MY_FALSE; }
  "json"               { return MY_JSON; }
  "service"            { return MY_SERVICE; }
  "flow"               { return MY_FLOW; }
  "return"             { return MY_RETURN; }
  "this"               { return MY_THIS; }

  {IDENTIFIER}         { return MY_IDENTIFIER; }
  {LINE_COMMENT}       { return MY_LINE_COMMENT; }
  {USI_VALUE}          { return MY_USI_VALUE; }
  {USI_KEY_NAME}       { return MY_USI_KEY_NAME; }
  {JSON_KEY_NAME}      { return MY_JSON_KEY_NAME; }
  {STRING}             { return MY_STRING; }
  {NUMBER}             { return MY_NUMBER; }

}

[^] { return BAD_CHARACTER; }
